/////////////////////////////////////////////////////////////////////////////
// Name:        Table_Diag.cpp
// Purpose:     Dialog for the Table
// Author:      Matthew Gong
// Created:     05/11/2005
// Copyright:   (c) Matthew Gong
// Licence:     GPL licence
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
// #pragma implementation
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

// -*- C++ -*- generated by wxGlade 0.3.5.1 on Wed May 11 08:33:48 2005

#include <wx/mstream.h>
#include <wx/txtstrm.h>
#include <wx/clipbrd.h>

#include "Table_Diag.h"
#include "TreeItem.h"
#include "Property_Diag.h"
#include "Commander.h"

class MyPlotCurve: public wxPlotCurve
{
public:
    MyPlotCurve(TableDialog * table)
     : wxPlotCurve( 0, -5.0, 5.0 ), Table(table), UPV(0.001), point(0) 
    {}

    virtual wxInt32 GetStartX()
        { return wxInt32(0); }
    virtual wxInt32 GetEndX()
        { return wxInt32((xvalue(size()-1)-xvalue(0))/UPV); }
    
    virtual double GetY( wxInt32 x );

    virtual int size()=0;
    virtual double yvalue(int)=0;
    virtual double xvalue(int)=0;

    double GetUPV() const
    {return UPV;}

protected:
    TableDialog * Table;
    double UPV;
    double StartX;
    double EndX;
    int point;
};

double MyPlotCurve::GetY( wxInt32 x )
{
  double dx = x * UPV + xvalue(0);

  while (point > 0 && xvalue(point)>=dx )
    --point;
  while (point+1 < size()-1 && xvalue(point+1)<dx )
    ++point;

  double scale = (dx-xvalue(point)) / (xvalue(point+1)-xvalue(point));
  if (scale < 0) scale = 0;
  if (scale > 1) scale = 1;

  return (yvalue(point+1)-yvalue(point))*scale + yvalue(point);
}

class MyPlotCurve4D: public MyPlotCurve
{
  public:
    MyPlotCurve4D(TableDialog * table, Table2D * tab, double width, int row, int col);
    
    int size()
    {
      switch (channel)
      {
        case 0:
          return cur_table->GetNumRows();
        case 1:
          return cur_table->GetNumCols();
        default :
          return 0;
      }
    }
    double yvalue(int i)
    {
      switch (channel)
      {
        case 0:
          return cur_table->GetValue(i+1, Col);
        case 1:
          return cur_table->GetValue(Row, i+1);
        default :
          return 0;
      }
    }
    double xvalue(int i)
    {
      switch (channel)
      {
        case 0:
          return cur_table->GetValue(i+1, 0u);
        case 1:
          return cur_table->GetValue(0u, i+1);
      }
    }
  protected:
    int Row, Col;
    int channel;
    Table2D * cur_table;
};

MyPlotCurve4D::MyPlotCurve4D(TableDialog * table, Table2D * tab, double width, int row, int col)
  : MyPlotCurve(table), Row(row), Col(col), cur_table(tab)
{
  if (Row > cur_table->GetNumRows() || Row < 1)
  {
    channel = 0;
    SetXLabel(Table->text_ctrl_property_row->GetValue());
    SetYLabel(wxString::Format(wxT("col=%g"), tab->GetValue(0u, col)));
  }
  else if (Col > cur_table->GetNumCols() || Col < 1)
  {
    channel = 1;
    SetXLabel(Table->text_ctrl_property_column->GetValue());
    SetYLabel(wxString::Format(wxT("row=%g"), tab->GetValue(row, 0u)));
  }
  double max, min;
  max = min = yvalue(0);
  for (int i=1; i < size(); ++i)
  {
    double tmp = yvalue(i);
    if (tmp>max)
      max = tmp;
    if (tmp<min)
      min = tmp;
  }
  double tmp = (max - min)*0.05;
  if (tmp == 0)
    tmp = 0.0001;
  UPV = (xvalue(size()-1)-xvalue(0)) / width;
  SetStartY(min - tmp);
  SetEndY(max + tmp);
  SetStartXVal(xvalue(0));
}

BEGIN_EVENT_TABLE(TableDialog, wxDialog)
  EVT_BUTTON(DETAIL_ROW, TableDialog::OnDetailRow)
  EVT_BUTTON(DETAIL_COLUMN, TableDialog::OnDetailCol)
  EVT_BUTTON(DETAIL_TABLE, TableDialog::OnDetailTab)
  EVT_BUTTON(DETAIL_FRAME, TableDialog::OnDetailFrm)
  EVT_BUTTON(CHS_ROW, TableDialog::OnChsRow)
  EVT_BUTTON(CHS_COLUMN, TableDialog::OnChsCol)
  EVT_BUTTON(CHS_TABLE, TableDialog::OnChsTab)
  EVT_BUTTON(CHS_FRAME, TableDialog::OnChsFrm)
  EVT_GRID_CMD_CELL_CHANGE(GRID_VALUE, TableDialog::OnChangeCellValue)
  EVT_GRID_CMD_CELL_LEFT_CLICK(GRID_VALUE, TableDialog::OnLeftClickGrid)
  EVT_COMBOBOX(TABLE_VALUE, TableDialog::OnUpdateGrid)
  EVT_COMBOBOX(FRAME_VALUE, TableDialog::OnUpdateGrid)
  EVT_BUTTON(APPLY, TableDialog::OnUpdateGrid)
  EVT_BUTTON(FILL_TABLE, TableDialog::OnReadInTablefromClipboard)
  EVT_BUTTON(REBUILD_TABLE, TableDialog::OnRebuildTable)
  EVT_BUTTON(REBUILD_FRAME, TableDialog::OnRebuildFrame)
  EVT_BUTTON(DRAW_CURVE, TableDialog::OnDrawCurve)
  EVT_BUTTON(ADD_CURVE, TableDialog::OnAddCurve)
  EVT_BUTTON(CLS_CURVE, TableDialog::OnClsCurve)
  EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, TableDialog::OnChangedPage)
END_EVENT_TABLE()


std::vector<double> readNumsfromClipboard()
{
  wxMemoryOutputStream mos;
  wxTextOutputStream tos(mos);

  wxClipboard clip;
  if (clip.Open())
  {
    if (clip.IsSupported( wxDF_TEXT ))
    {
      wxTextDataObject data; 
      clip.GetData( data );
      tos.WriteString(data.GetText()); 
    }   
    wxTheClipboard->Close();
  }

  wxMemoryInputStream mis(mos);
  wxTextInputStream tis(mis);
  tis.SetStringSeparators(wxT("\t, "));


  std::vector<double> list;

  while (!mis.Eof())
  {
    wxString tmp = tis.ReadWord();
    int i = 0;
    while (tmp[i] == ' ') ++i;
    int j = tmp.Length() - 1;
    while (tmp[j] == ' ') --j;
    tmp = tmp.Mid(i, j-i+1);
    double tmpd;
    if (tmp.ToDouble(&tmpd))
    {
      list.push_back(tmpd);
    }
  }

  return list;
}

std::vector<double> readNumsfromString(const wxString & str)
{
  std::vector<double> list;

  wxMemoryInputStream mis(str, str.Length());
  wxTextInputStream tis(mis);
  tis.SetStringSeparators(wxT("\t, "));

  while (!mis.Eof())
  {
    wxString tmp = tis.ReadWord();
    int i = 0;
    while (tmp[i] == ' ') ++i;
    int j = tmp.Length() - 1;
    while (tmp[j] == ' ') --j;
    tmp = tmp.Mid(i, j-i+1);
    double tmpd;
    if (tmp.ToDouble(&tmpd))
    {
      list.push_back(tmpd);
    }
  }

  return list;
}

TableDialog::TableDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxDialog(parent, id, title, pos, size, style)
{
    // begin wxGlade: TableDialog::TableDialog
    notebook_main = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize, 0);
    notebook_main_pane_3 = new wxPanel(notebook_main, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
    notebook_main_pane_2 = new wxPanel(notebook_main, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
    sizer_9_staticbox = new wxStaticBox(notebook_main_pane_2, -1, _("choice"));
    sizer_12_staticbox = new wxStaticBox(notebook_main_pane_3, -1, _("setting"));
    label_name = new wxStaticText(notebook_main_pane_2, -1, _("Name:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    text_ctrl_name = new wxTextCtrl(notebook_main_pane_2, -1, wxT(""), wxDefaultPosition, wxDefaultSize);
    label_property_row = new wxStaticText(notebook_main_pane_2, -1, _("row property:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    text_ctrl_property_row = new wxTextCtrl(notebook_main_pane_2, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
    button_chs_row = new wxButton(notebook_main_pane_2, CHS_ROW, wxT("..."));
    button_detail_row = new wxButton(notebook_main_pane_2, DETAIL_ROW, _("row detail"));
    label_property_column = new wxStaticText(notebook_main_pane_2, -1, _("column property:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    text_ctrl_property_column = new wxTextCtrl(notebook_main_pane_2, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
    button_chs_column = new wxButton(notebook_main_pane_2, CHS_COLUMN, wxT("..."));
    button_detail_column = new wxButton(notebook_main_pane_2, DETAIL_COLUMN, _("column detail"));
    label_property_table = new wxStaticText(notebook_main_pane_2, -1, _("table property:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    text_ctrl_property_table = new wxTextCtrl(notebook_main_pane_2, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
    button_chs_table = new wxButton(notebook_main_pane_2, CHS_TABLE, wxT("..."));
    button_detail_table = new wxButton(notebook_main_pane_2, DETAIL_TABLE, _("table detail"));
    label_property_frame = new wxStaticText(notebook_main_pane_2, -1, _("frame property:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    text_ctrl_property_frame = new wxTextCtrl(notebook_main_pane_2, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
    button_chs_frame = new wxButton(notebook_main_pane_2, CHS_FRAME, wxT("..."));
    button_detail_frame = new wxButton(notebook_main_pane_2, DETAIL_FRAME, _("frame detail"));
    label_table_value = new wxStaticText(notebook_main_pane_2, -1, _("table ="), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    const wxString combo_box_table_value_choices[] = {
        
    };
    combo_box_table_value = new wxComboBox(notebook_main_pane_2, TABLE_VALUE, wxT(""), wxDefaultPosition, wxDefaultSize, 0, combo_box_table_value_choices, wxCB_DROPDOWN|wxCB_READONLY);
    label_frame_value = new wxStaticText(notebook_main_pane_2, -1, _("frame ="), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
    const wxString combo_box_frame_value_choices[] = {
        
    };
    combo_box_frame_value = new wxComboBox(notebook_main_pane_2, FRAME_VALUE, wxT(""), wxDefaultPosition, wxDefaultSize, 0, combo_box_frame_value_choices, wxCB_DROPDOWN|wxCB_READONLY);
    grid_value = new wxGrid(notebook_main_pane_2, GRID_VALUE);
    button_apply = new wxButton(notebook_main_pane_2, APPLY, _("Apply"));
    button_fill_table = new wxButton(notebook_main_pane_2, FILL_TABLE, _("fill table"));
    button_recreate_table = new wxButton(notebook_main_pane_2, REBUILD_TABLE, _("rebuild table"));
    button_recreate_frame = new wxButton(notebook_main_pane_2, REBUILD_FRAME, _("rebuild frame"));
    label_info2 = new wxStaticText(notebook_main_pane_3, -1, wxT(""));
    label_row = new wxStaticText(notebook_main_pane_3, -1, _("row="));
    const wxString combo_box_row_choices[] = {
        
    };
    combo_box_row = new wxComboBox(notebook_main_pane_3, LINE_ROW, wxT(""), wxDefaultPosition, wxDefaultSize, 0, combo_box_row_choices, wxCB_DROPDOWN|wxCB_READONLY);
    label_column = new wxStaticText(notebook_main_pane_3, -1, _("column="));
    const wxString combo_box_column_choices[] = {
        
    };
    combo_box_column = new wxComboBox(notebook_main_pane_3, LINE_COL, wxT(""), wxDefaultPosition, wxDefaultSize, 0, combo_box_column_choices, wxCB_DROPDOWN|wxCB_READONLY);
    button_draw = new wxButton(notebook_main_pane_3, DRAW_CURVE, _("Redraw"));
    button_add_draw = new wxButton(notebook_main_pane_3, ADD_CURVE, _("Add"));
    button_cls_draw = new wxButton(notebook_main_pane_3, CLS_CURVE, _("Clear"));
    window_draw = new wxPlotWindow(notebook_main_pane_3, -1, wxDefaultPosition, wxSize(600,400), wxPLOT_Y_AXIS|wxPLOT_X_AXIS);
    window_draw->SameRange(true);
    button_ok = new wxButton(this, wxID_OK, _("OK"));
    button_cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));

    set_properties();
    do_layout();
    // end wxGlade

    cur_col_no = 0;
    cur_row_no = 0;
    cur_table  = NULL;
}


void TableDialog::set_properties()
{
    // begin wxGlade: TableDialog::set_properties
    label_name->SetMinSize(wxSize(120, 20));
    label_property_row->SetMinSize(wxSize(120, 20));
    label_property_column->SetMinSize(wxSize(120, 20));
    label_property_table->SetMinSize(wxSize(120, 20));
    label_property_frame->SetMinSize(wxSize(120, 20));
    label_table_value->SetMinSize(wxSize(60, 20));
    combo_box_table_value->SetSelection(-1);
    label_frame_value->SetMinSize(wxSize(60, 20));
    combo_box_frame_value->SetSelection(-1);
    //grid_value->CreateGrid(10, 1);
    //grid_value->SetRowLabelSize(30);
    //grid_value->SetColLabelSize(30);
    combo_box_row->SetMinSize(wxSize(70, 29));
    combo_box_row->SetSelection(-1);
    combo_box_column->SetMinSize(wxSize(70, 29));
    combo_box_column->SetSelection(-1);
    notebook_main->SetMinSize(wxSize(600, 580));
    // end wxGlade
}


void TableDialog::do_layout()
{
    // begin wxGlade: TableDialog::do_layout
    wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_6 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_11 = new wxBoxSizer(wxVERTICAL);
    wxStaticBoxSizer* sizer_12 = new wxStaticBoxSizer(sizer_12_staticbox, wxHORIZONTAL);
    wxBoxSizer* sizer_7 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_8 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_10 = new wxBoxSizer(wxVERTICAL);
    wxStaticBoxSizer* sizer_9 = new wxStaticBoxSizer(sizer_9_staticbox, wxHORIZONTAL);
    wxBoxSizer* sizer_name = new wxBoxSizer(wxHORIZONTAL);
    sizer_name->Add(label_name, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_name->Add(text_ctrl_name, 1, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_name, 0, wxALL|wxEXPAND, 5);
    wxBoxSizer* sizer_4_copy_2 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_4_copy_1 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_4_copy = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_4 = new wxBoxSizer(wxHORIZONTAL);
    sizer_4_copy_2->Add(label_property_frame, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_4_copy_2->Add(text_ctrl_property_frame, 1, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_4_copy_2->Add(button_chs_frame, 0, wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_4_copy_2, 0, wxALL|wxEXPAND, 5);
    sizer_4_copy_1->Add(label_property_table, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_4_copy_1->Add(text_ctrl_property_table, 1, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_4_copy_1->Add(button_chs_table, 0, wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_4_copy_1, 0, wxALL|wxEXPAND, 5);
    sizer_4_copy->Add(label_property_column, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_4_copy->Add(text_ctrl_property_column, 1, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_4_copy->Add(button_chs_column, 0, wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_4_copy, 0, wxALL|wxEXPAND, 5);
    sizer_4->Add(label_property_row, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_4->Add(text_ctrl_property_row, 1, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_4->Add(button_chs_row, 0, wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_4, 0, wxALL|wxEXPAND, 5);
    sizer_9->Add(label_frame_value, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    sizer_9->Add(combo_box_frame_value, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_9->Add(label_table_value, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);
    sizer_9->Add(combo_box_table_value, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_9->Add(button_apply, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_7->Add(sizer_9, 0, wxALL|wxEXPAND, 5);
    sizer_8->Add(grid_value, 1, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_detail_row, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_detail_column, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_detail_table, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_detail_frame, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_fill_table, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_recreate_table, 0, wxALL|wxEXPAND, 5);
    sizer_10->Add(button_recreate_frame, 0, wxALL|wxEXPAND, 5);
    sizer_8->Add(sizer_10, 0, wxALL|wxEXPAND, 5);
    sizer_7->Add(sizer_8, 1, wxEXPAND, 0);
    notebook_main_pane_2->SetAutoLayout(true);
    notebook_main_pane_2->SetSizer(sizer_7);
    sizer_7->Fit(notebook_main_pane_2);
    sizer_7->SetSizeHints(notebook_main_pane_2);
    sizer_11->Add(label_info2, 0, wxALL|wxEXPAND, 5);
    sizer_12->Add(label_row, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_12->Add(combo_box_row, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_12->Add(label_column, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_12->Add(combo_box_column, 0, wxALL|wxALIGN_CENTER_VERTICAL, 3);
    sizer_12->Add(button_add_draw, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_12->Add(button_cls_draw, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_12->Add(button_draw, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
    sizer_11->Add(sizer_12, 0, wxALL|wxEXPAND, 3);
    sizer_11->Add(window_draw, 1, wxALL|wxEXPAND, 5);
    notebook_main_pane_3->SetAutoLayout(true);
    notebook_main_pane_3->SetSizer(sizer_11);
    sizer_11->Fit(notebook_main_pane_3);
    sizer_11->SetSizeHints(notebook_main_pane_3);
    notebook_main->AddPage(notebook_main_pane_2, _("value"));
    notebook_main->AddPage(notebook_main_pane_3, _("line"));
    sizer_1->Add(notebook_main, 1, wxALL|wxEXPAND, 3);
    sizer_6->Add(button_ok, 1, wxALL, 10);
    sizer_6->Add(button_cancel, 1, wxALL, 10);
    sizer_1->Add(sizer_6, 0, wxALL|wxEXPAND, 5);
    SetAutoLayout(true);
    SetSizer(sizer_1);
    sizer_1->Fit(this);
    sizer_1->SetSizeHints(this);
    Layout();
    window_draw->Layout();
    // end wxGlade
}

void TableDialog::Load(TreeItemData_Table * data)
{
  GetPropertyDialog()->Update();

  Type = data->Type;
  switch (Type)
  {
    case TreeItemData_Table::tt1D :
    case TreeItemData_Table::tt2D :
      value_2d = data->value_2d;
      break;
    case TreeItemData_Table::tt3D :
      value_3d = data->value_3d;
      break;
    case TreeItemData_Table::tt4D :
      value_4d = data->value_4d;
      break;
  }

  text_ctrl_name->SetValue(data->name);
  
  text_ctrl_property_row->SetValue(data->independentVar_row);
  text_ctrl_property_column->SetValue(data->independentVar_column);
  text_ctrl_property_table->SetValue(data->independentVar_table);
  text_ctrl_property_frame->SetValue(data->independentVar_frame);

  reinit();

  clearCurves();
  notebook_main_pane_2->Layout();
  notebook_main_pane_2->Refresh();
  notebook_main_pane_2->Update();
}

void TableDialog::reinit()
{
  switch(Type)
  {
    case TreeItemData_Table::tt1D :
      {
        label_property_column->Show(false);
        text_ctrl_property_column->Show(false);
        button_chs_column->Show(false);
        button_detail_column->Show(false);
        label_property_table->Show(false);
        text_ctrl_property_table->Show(false);
        button_chs_table->Show(false);
        button_detail_table->Show(false);
        label_property_frame->Show(false);
        text_ctrl_property_frame->Show(false);
        button_chs_frame->Show(false);
        button_detail_frame->Show(false);
        //sizer_9_staticbox->Show(false);
        label_table_value->Show(false);
        combo_box_table_value->Show(false);
        label_frame_value->Show(false);
        combo_box_frame_value->Show(false);
        button_recreate_table->Show(false);
        button_recreate_frame->Show(false);
        sizer_12_staticbox->Show(false);
        label_row->Show(false);
        combo_box_row->Show(false);
        label_column->Show(false);
        combo_box_column->Show(false);
        button_add_draw->Show(false);
        button_cls_draw->Show(false);
        button_draw->Show(false);
        cur_table = &value_2d;
        updateGrid1D();
      }
      break;
    case TreeItemData_Table::tt2D :
      {
        label_property_table->Show(false);
        text_ctrl_property_table->Show(false);
        button_chs_table->Show(false);
        button_detail_table->Show(false);
        label_property_frame->Show(false);
        text_ctrl_property_frame->Show(false);
        button_chs_frame->Show(false);
        button_detail_frame->Show(false);
        //sizer_9_staticbox->Show(false);
        label_table_value->Show(false);
        combo_box_table_value->Show(false);
        label_frame_value->Show(false);
        combo_box_frame_value->Show(false);
        button_recreate_frame->Show(false);

        cur_table = &value_2d;
        updateGrid2D();
      }
      break;
    case TreeItemData_Table::tt3D :
      {
        label_property_frame->Show(false);
        text_ctrl_property_frame->Show(false);
        button_chs_frame->Show(false);
        button_detail_frame->Show(false);
        label_frame_value->Show(false);
        combo_box_frame_value->Show(false);
        
        wxString str = combo_box_table_value->GetValue();
        combo_box_table_value->Clear();
        std::vector<double> tmp = value_3d.GetKeyList();
        for (std::vector<double>::iterator i = tmp.begin();
            i != tmp.end(); ++i)
        {
          combo_box_table_value->Append(wxString::Format(wxT("%g"), *i));
        }
        if (! combo_box_table_value->SetStringSelection(str))
        {
          combo_box_table_value->SetSelection(0);
        }
        str = combo_box_table_value->GetValue();
        double d;
        str.ToDouble(&d);
        cur_table = value_3d.GetTable(d);

        updateGrid2D();
      }
      break;
    case TreeItemData_Table::tt4D :
      {
        wxString str2 = combo_box_frame_value->GetValue();
        combo_box_frame_value->Clear();
        std::vector<double> tmp = value_4d.GetKeyList();
        for (std::vector<double>::iterator i = tmp.begin();
            i != tmp.end(); ++i)
        {
          combo_box_frame_value->Append(wxString::Format(wxT("%g"), *i));
        }
        if (! combo_box_frame_value->SetStringSelection(str2))
        {
          combo_box_frame_value->SetSelection(0);
        }
        str2 = combo_box_frame_value->GetValue();
        double d2;
        str2.ToDouble(&d2);
        Table3D * t3d = value_4d.GetTable(d2);
        
        wxString str = combo_box_table_value->GetValue();
        combo_box_table_value->Clear();
        if (t3d)
        {
          std::vector<double> tmp = t3d->GetKeyList();
          for (std::vector<double>::iterator i = tmp.begin();
            i != tmp.end(); ++i)
          {
            combo_box_table_value->Append(wxString::Format(wxT("%g"), *i));
          }
          if (! combo_box_table_value->SetStringSelection(str))
          {
            combo_box_table_value->SetSelection(0);
          }
          str = combo_box_table_value->GetValue();
          double d;
          str.ToDouble(&d);
          cur_table = t3d->GetTable(d);
        }
        else
        {
          cur_table = NULL;
        }
        updateGrid2D();
      }
      break;
    default :
      {
        throw _("Error table type");
      }
      break;
  }
}

void TableDialog::Save(TreeItemData_Table * data)
{
  data->Type = Type;
  if (!text_ctrl_name->GetValue().IsEmpty())
    data->name = text_ctrl_name->GetValue();

  data->independentVar_row = text_ctrl_property_row->GetValue();
  data->independentVar_column = text_ctrl_property_column->GetValue();
  data->independentVar_table = text_ctrl_property_table->GetValue();
  data->independentVar_frame = text_ctrl_property_frame->GetValue();

  switch (Type)
  {
    case TreeItemData_Table::tt1D :
    case TreeItemData_Table::tt2D :
      data->value_2d = value_2d;
      break;
    case TreeItemData_Table::tt3D :
      data->value_3d = value_3d;
      break;
    case TreeItemData_Table::tt4D :
      data->value_4d = value_4d;
      break;
  }
  data->tree->SetItemText(data->GetId(), data->GetExpression());
}

void TableDialog::updateGrid1D()
{
  if (cur_table)
  {
    unsigned int nRows = cur_table->GetNumRows();
    if (grid_value->CreateGrid(nRows, 1))
    {
      grid_value->SetRowLabelSize(100);
      grid_value->SetColLabelSize(30);
    }
    else
    {
      grid_value->BeginBatch();
      bool flag = true;
      while (grid_value->GetNumberRows() > nRows && flag)
      {
        flag = grid_value->DeleteRows();
      }
      flag = true;
      while (grid_value->GetNumberRows() < nRows && flag)
      {
        flag = grid_value->AppendRows();
      }
      grid_value->EndBatch();
    }

    grid_value->BeginBatch();
    grid_value->SetColLabelValue(0, _("Value"));
    for (int i=1; i<= nRows; ++i)
    {
      grid_value->SetRowLabelValue(i-1, wxString::Format("%g", cur_table->GetValue(i, 0u)));
      grid_value->SetCellValue(i-1, 0, wxString::Format("%g", cur_table->GetValue(i, 1u)));
    }
    grid_value->EndBatch();
  }
}

void TableDialog::updateGrid2D()
{
  if (cur_table)
  {
    unsigned int nRows = cur_table->GetNumRows();
    unsigned int nCols = cur_table->GetNumCols();
    if (grid_value->CreateGrid(nRows, nCols))
    {
      grid_value->SetRowLabelSize(100);
      grid_value->SetColLabelSize(30);
    }
    else
    {
      grid_value->BeginBatch();
      bool flag = true;
      while (grid_value->GetNumberCols() > nCols && flag)
      {
        flag = grid_value->DeleteCols();
      }
      flag = true;
      while (grid_value->GetNumberCols() < nCols && flag)
      {
        flag = grid_value->AppendCols();
      }
      flag = true;
      while (grid_value->GetNumberRows() > nRows && flag)
      {
        flag = grid_value->DeleteRows();
      }
      flag = true;
      while (grid_value->GetNumberRows() < nRows && flag)
      {
        flag = grid_value->AppendRows();
      }
      grid_value->EndBatch();
    }
    
    grid_value->BeginBatch();
    for (int i=1; i <= nCols; ++i)
      grid_value->SetColLabelValue(i-1, wxString::Format("%g", cur_table->GetValue(0u, i)));
    for (int i=1; i <= nRows; ++i)
    {
      grid_value->SetRowLabelValue(i-1, wxString::Format("%g", cur_table->GetValue(i, 0u)));
      for (int j=1; j <= nCols; ++j)
        grid_value->SetCellValue(i-1, j-1, wxString::Format("%g", cur_table->GetValue(i, j)));
    }
    grid_value->EndBatch();
  }
}

void TableDialog::OnChangeCellValue(wxGridEvent & event)
{
  if (cur_table)
  {
    int col_no = event.GetCol();
    int row_no = event.GetRow();

    double tmp;
    double old_value = cur_table->GetValue(row_no+1, col_no+1);
    if (grid_value->GetCellValue(row_no, col_no).ToDouble(&tmp))
    {
      cur_table->SetValue(row_no+1, col_no+1, tmp);
    }
    else
    {
      grid_value->BeginBatch();
      grid_value->SetCellValue(row_no, col_no, wxString::Format("%g", old_value));
      grid_value->EndBatch();
    }
  }
}

void TableDialog::OnLeftClickGrid(wxGridEvent & event)
{
  cur_col_no = event.GetCol();
  cur_row_no = event.GetRow();
  event.Skip();
}

void TableDialog::OnUpdateGrid(wxCommandEvent & event)
{
  switch (Type)
  {
    case TreeItemData_Table::tt1D :
      updateGrid1D();
      break;
    case TreeItemData_Table::tt2D :
      {
        cur_table = &value_2d;
        updateGrid2D();
      }
      break;
    case TreeItemData_Table::tt3D :
      {
        wxString str = combo_box_table_value->GetValue();
        double d;
        if (str.ToDouble(&d))
        {
          Table2D *tmp_table = value_3d.GetTable(d);
          if (tmp_table)
          {
            cur_table = tmp_table;
            updateGrid2D();
          }
        }
      }
      break;
    case TreeItemData_Table::tt4D :
      {
        wxString str2  = combo_box_frame_value->GetValue();
        double d2;
        str2.ToDouble(&d2);
        Table3D * t3d = value_4d.GetTable(d2);
        
	wxString str = combo_box_table_value->GetValue();
        if (t3d)
        {
          combo_box_table_value->Clear();
          std::vector<double> tmp = t3d->GetKeyList();
          for (std::vector<double>::iterator i = tmp.begin();
            i != tmp.end(); ++i)
          {
            combo_box_table_value->Append(wxString::Format(wxT("%g"), *i));
          }
	  combo_box_table_value->SetValue(str);
          str = combo_box_table_value->GetValue();
          double d;
          str.ToDouble(&d);
          cur_table = t3d->GetTable(d);
          updateGrid2D();
        }
      }
      break;
    default :
      {
        throw _("Error table type");
      }
      break;
  }
}

void TableDialog::OnReadInTablefromClipboard(wxCommandEvent & event)
{
  if (!cur_table)
    return;

  std::vector<double> list = readNumsfromClipboard();

  if (list.size()<1)
    return;

  if (::wxMessageBox(_("Do you want to add ") + wxString::Format("%d", list.size()) + _(" numbers from clipboard to grid from row=") + wxString::Format("%d", cur_row_no) + _(", col=") + wxString::Format("%d", cur_col_no), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) == wxYES)
  {
    unsigned int nRows = cur_table->GetNumRows();
    unsigned int nCols = cur_table->GetNumCols();
    unsigned int row = cur_row_no+1;
    unsigned int col = cur_col_no+1;
    for (int i=0; i<list.size(); ++i)
    {
      cur_table->SetValue(row, col, list[i]);
      ++col;
      if (col > nCols)
      {
        ++row;
        col = 1u;
      }
      if (row > nRows)
      {
        break;
      }
    }
    switch (Type)
    {
    case TreeItemData_Table::tt1D :
      updateGrid1D();
      break;
    default :
      updateGrid2D();
      break;
    }
  }
}

void TableDialog::OnRebuildTable(wxCommandEvent & event)
{
  if (!cur_table)
    return;

  std::vector<double> list = readNumsfromClipboard();

  unsigned int nCols = (unsigned int)list[0];
  unsigned int nRows = (unsigned int)list[1];
  if (list.size() == 2+nCols+nRows+nCols*nRows && nCols > 1 && nRows > 1)
  {
    if (::wxMessageBox(_("Do you want to rebuild the current 2D table ") + wxString::Format("in %d cols and %d rows using %d", nCols, nRows, list.size()) + _(" numbers from clipboard"), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) == wxYES)
    {
      int i = 2;
      cur_table->SetTable(nRows, nCols);
      for (unsigned int j = 1u; j <= nCols; ++j)
      {
        cur_table->SetValue(0u, j, list[i++]);
      }
      for (unsigned int j = 1u; j <= nRows; ++j)
      {
        cur_table->SetValue(j, 0u, list[i++]);
      }
      for (unsigned int j = 1u; j <= nRows; ++j)
      {
        for (unsigned int k = 1u; k <= nCols; ++k)
        {
          cur_table->SetValue(j, k, list[i++]);
        }
      }
      switch (Type)
      {
      case TreeItemData_Table::tt1D :
        updateGrid1D();
        break;
      default :
        updateGrid2D();
        break;
      }
    }
  }
  else
  {
    wxLogMessage(_("fail to parse data format from clipboard"));
  }
}

void TableDialog::OnRebuildFrame(wxCommandEvent & event)
{
  std::vector<double> list = readNumsfromClipboard();

  unsigned int nCols = (unsigned int)list[0];
  unsigned int nRows = (unsigned int)list[1];
  unsigned int nTables = (unsigned int)list[2];
  if (list.size() == 3+nCols+nRows+nTables+nCols*nRows*nTables && nCols > 1 && nRows > 1 && nTables > 1)
  {
    if (::wxMessageBox(_("Do you want to rebuild the 3D table ") + wxString::Format("in %d cols , %d rows and %d tables using %d", nCols, nRows, nTables, list.size()) + _(" numbers from clipboard"), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) == wxYES)
    {
      int i = 3;
      Table3D tab3d;
      Table2D tab(nRows, nCols);
      for (unsigned int j = 1u; j <= nCols; ++j)
      {
        tab.SetValue(0u, j, list[i++]);
      }
      for (unsigned int j = 1u; j <= nRows; ++j)
      {
        tab.SetValue(j, 0u, list[i++]);
      }
      tab3d.Clear();
      for (unsigned int j = 1u; j <= nTables; ++j)
      {
        tab3d.AddTable(list[i++], tab);
      }
      
      for ( Table3D::VALUE_TYPE::iterator iter = tab3d.GetTable().begin();
          iter != tab3d.GetTable().end(); ++iter)
      {
        for (unsigned int j = 1u; j <= nRows; ++j)
        {
          for (unsigned int k = 1u; k <= nCols; ++k)
          {
            (*iter).second.SetValue(j, k, list[i++]);
          }
        }
      }
      switch (Type)
      {
      case TreeItemData_Table::tt3D :
        value_3d = tab3d;
        reinit();
        break;
      case TreeItemData_Table::tt4D :
        {
          wxString str2 = combo_box_frame_value->GetValue();
          double d2;
          str2.ToDouble(&d2);
          Table3D * t3d = value_4d.GetTable(d2);
          (*t3d) = tab3d;
          reinit();
        }
        break;
      default :
        break;
      }
    }
  }
  else
  {
    wxLogMessage(_("fail to parse data format from clipboard"));
  }
}

void TableDialog::clearCurves()
{
  for ( std::vector< MyPlotCurve4D * >::iterator iter = curves.begin();
      iter != curves.end();
      ++iter)
  {
    window_draw->Delete(*iter);
  }
  curves.clear();
}

void TableDialog::updateCurves()
{
  window_draw->RedrawEverything();
}

void TableDialog::appendCurve()
{
  if (!cur_table)
  {
    return;
  }
  unsigned int nRows = cur_table->GetNumRows();
  unsigned int nCols = cur_table->GetNumCols();
  int w, h;
  window_draw->GetClientSize(&w, &h);
  MyPlotCurve4D * curve = NULL;
  switch (Type)
  {
    case TreeItemData_Table::tt1D :
      {
        curve = new MyPlotCurve4D(this, cur_table, w - 114, 0, 1);
      }
      break;
    default :
      {
        int r = combo_box_row->GetSelection();
        int c = combo_box_column->GetSelection();
        if (r>=1 && r<=nRows && (c<1 || c>nCols) || (r<1 || r>nRows) && c>=1 && c<=nCols)
        {
          curve = new MyPlotCurve4D(this, cur_table, w - 114, r, c);
        }
      }
      break;
  }
  if (curve)
  {
    curves.push_back(curve);
    window_draw->SetUnitsPerValue( curve->GetUPV() );
    window_draw->Add(curve);
    window_draw->Layout();
    window_draw->RedrawEverything();
  }
}

void TableDialog::OnDrawCurve(wxCommandEvent & event)
{
  updateCurves();
}

void TableDialog::OnAddCurve(wxCommandEvent & event)
{
  appendCurve();
}

void TableDialog::OnClsCurve(wxCommandEvent & event)
{
  clearCurves();
}

void TableDialog::OnDetailRow(wxCommandEvent & event)
{
  if (!cur_table)
    return;
  
  unsigned int nRows = cur_table->GetNumRows();
  unsigned int nCols = cur_table->GetNumCols();
  std::vector<double> row;
  for (unsigned int i = 1; i<=nRows; ++i)
  {
    row.push_back(cur_table->GetValue(i, 0u));
  }
  std::vector<double> col;
  for (unsigned int i = 1; i<=nCols; ++i)
  {
    col.push_back(cur_table->GetValue(0u, i));
  }
  ParameterDialog dlg(this, -1, _("Show the list of Row"));
  dlg.Load(row , true, true);
  if (dlg.ShowModal() == wxID_OK)
  {
    std::vector<double> tmp = dlg.Save();
    bool flag;
    if (tmp.size() == row.size())
    {
      flag = false;
    }
    else
    {
      if (wxMessageBox(_("All the data in the table will be set to zero. Do you want to continue?"), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) != wxYES)
      {
        return;
      }
      flag = true;
    }
    if (flag)
    {
      wxLogMessage(_("All the data in the table has been set to zero."));
      cur_table->SetNumRows(tmp.size());
    }
    nRows = tmp.size();
    for (unsigned int i = 1; i<=nRows; ++i)
    {
      cur_table->SetValue(i, 0u, tmp[i-1]);
    }
    for (unsigned int i = 1; i<=nCols; ++i)
    {
      cur_table->SetValue(0u, i, col[i-1]);
    }
    
    reinit();
  }
}

void TableDialog::OnDetailCol(wxCommandEvent & event)
{
  if (!cur_table)
    return;
  
  unsigned int nRows = cur_table->GetNumRows();
  unsigned int nCols = cur_table->GetNumCols();
  std::vector<double> row;
  for (unsigned int i = 1; i<=nRows; ++i)
  {
    row.push_back(cur_table->GetValue(i, 0u));
  }
  std::vector<double> col;
  for (unsigned int i = 1; i<=nCols; ++i)
  {
    col.push_back(cur_table->GetValue(0u, i));
  }
  ParameterDialog dlg(this, -1, _("Show the list of Column"));
  dlg.Load(col , true, true);
  if (dlg.ShowModal() == wxID_OK)
  {
    std::vector<double> tmp = dlg.Save();
    bool flag;
    if (tmp.size() == col.size())
    {
      flag = false;
    }
    else
    {
      if (wxMessageBox(_("All the data in the table will be set to zero. Do you want to continue?"), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) != wxYES)
      {
        return;
      }
      flag = true;
    }
    if (flag)
    {
      wxLogMessage(_("All the data in the table has been set to zero."));
      cur_table->SetNumCols(tmp.size());
    }
    nCols = tmp.size();
    for (unsigned int i = 1; i<=nCols; ++i)
    {
      cur_table->SetValue(0u, i, tmp[i-1]);
    }
    for (unsigned int i = 1; i<=nRows; ++i)
    {
      cur_table->SetValue(i, 0u, row[i-1]);
    }
    reinit();
  }
}

void TableDialog::OnDetailTab(wxCommandEvent & event)
{
  std::vector<double> tablist;
  Table3D * t3d = NULL;
  switch (Type)
  {
  case TreeItemData_Table::tt3D :
    t3d = &value_3d;
    tablist = t3d->GetKeyList();
    break;
  case TreeItemData_Table::tt4D :
    {
      wxString str = combo_box_frame_value->GetValue();
      double d;
      str.ToDouble(&d);
      t3d = value_4d.GetTable(d);
      if (t3d)
      {
        tablist = t3d->GetKeyList();
      }
      else
      {
        return;
      }
    }
    break;
  default :
    return;
  }
  ParameterDialog dlg(this, -1, _("Show the list of Table"));
  dlg.Load(tablist, true, true);
  if (dlg.ShowModal() == wxID_OK)
  {
    std::vector<double> tmp = dlg.Save();
    for (std::vector<double>::iterator i = tmp.begin(); i != tmp.end(); ++i)
    {
      if (! t3d->GetTable(*i))
      {
        t3d->AddTable(*i, Table2D());
      }
    }
    for (std::vector<double>::iterator i = tablist.begin(); 
        i != tablist.end(); ++i)
    {
      if (std::find(tmp.begin(), tmp.end(), *i) == tmp.end())
      {
        t3d->RemoveTable(*i);
      }
    }
    reinit();
  }
}

void TableDialog::OnDetailFrm(wxCommandEvent & event)
{
  if (Type != TreeItemData_Table::tt4D )
  {
    return;
  }
  
  Table4D * t4d = &value_4d;
  std::vector<double> frmlist = t4d->GetKeyList();
  ParameterDialog dlg(this, -1, _("Show the list of Frame"));
  dlg.Load(frmlist , true, true);
  if (dlg.ShowModal() == wxID_OK)
  {
    std::vector<double> tmp = dlg.Save();
    for (std::vector<double>::iterator i = tmp.begin(); i != tmp.end(); ++i)
    {
      if (! t4d->GetTable(*i))
      {
        
        t4d->AddTable(*i, Table3D());
      }
    }
    for (std::vector<double>::iterator i = frmlist.begin(); 
        i != frmlist.end(); ++i)
    {
      if (std::find(tmp.begin(), tmp.end(), *i) == tmp.end())
      {
        t4d->RemoveTable(*i);
      }
    }
    reinit();
  }
}

void TableDialog::OnChsRow(wxCommandEvent & event)
{
  wxString tmp = text_ctrl_property_row->GetValue();
  GetPropertyDialog()->Select(tmp);
  if (GetPropertyDialog()->ShowModal() == wxID_OK)
  {
    text_ctrl_property_row->SetValue(GetPropertyDialog()->GetResult());
  }
}

void TableDialog::OnChsCol(wxCommandEvent & event)
{
  wxString tmp = text_ctrl_property_column->GetValue();
  GetPropertyDialog()->Select(tmp);
  if (GetPropertyDialog()->ShowModal() == wxID_OK)
  {
    text_ctrl_property_column->SetValue(GetPropertyDialog()->GetResult());
  }
}

void TableDialog::OnChsTab(wxCommandEvent & event)
{
  wxString tmp = text_ctrl_property_table->GetValue();
  GetPropertyDialog()->Select(tmp);
  if (GetPropertyDialog()->ShowModal() == wxID_OK)
  {
    text_ctrl_property_table->SetValue(GetPropertyDialog()->GetResult());
  }
}

void TableDialog::OnChsFrm(wxCommandEvent & event)
{
  wxString tmp = text_ctrl_property_frame->GetValue();
  GetPropertyDialog()->Select(tmp);
  if (GetPropertyDialog()->ShowModal() == wxID_OK)
  {
    text_ctrl_property_frame->SetValue(GetPropertyDialog()->GetResult());
  }
}

void TableDialog::OnChangedPage(wxNotebookEvent & event)
{
  if (event.GetSelection() == 0)
  {
    clearCurves();
    return;
  }

  wxString tmp;
  switch (Type)
  {
    case TreeItemData_Table::tt4D :
      tmp += wxString(_("Frame : ")) + text_ctrl_property_frame->GetValue() + wxT(" = ") + combo_box_frame_value->GetValue() + wxT(";\n");
    case TreeItemData_Table::tt3D :
      tmp += wxString(_("Table : ")) + text_ctrl_property_table->GetValue() + wxT(" = ") + combo_box_table_value->GetValue() + wxT(";\n");
    case TreeItemData_Table::tt2D :
      tmp += wxString(_("Column : ")) + text_ctrl_property_column->GetValue() + wxT(";\n");
    case TreeItemData_Table::tt1D :
      tmp += wxString(_("Row : ")) + text_ctrl_property_row->GetValue() + wxT(";");
  }
  label_info2->SetLabel(tmp);
  notebook_main_pane_3->Layout();
  combo_box_row->Clear();
  combo_box_column->Clear();
  switch (Type)
  {
  case TreeItemData_Table::tt1D :
    {
      appendCurve();
    }
    break;
  default :
    if (cur_table)
    {
      unsigned int nRows = cur_table->GetNumRows();
      unsigned int nCols = cur_table->GetNumCols();
      combo_box_row->Append(wxEmptyString);
      for (unsigned int i = 1; i <= nRows; ++i)
      {
         combo_box_row->Append(wxString::Format(wxT("%g"), 
               cur_table->GetValue(i, 0u)));
      }
      combo_box_column->Append(wxEmptyString);
      for (unsigned int i = 1; i <= nCols; ++i)
      {
         combo_box_column->Append(wxString::Format(wxT("%g"), 
               cur_table->GetValue(0u, i)));
      }
    }
  }
}



BEGIN_EVENT_TABLE(ParameterDialog, wxDialog)
  EVT_BUTTON(ADD_STR, ParameterDialog::OnAddStr)
  EVT_BUTTON(ADD_CLIP, ParameterDialog::OnAddClip)
  EVT_BUTTON(DEL_ONE, ParameterDialog::OnDelOne)
END_EVENT_TABLE()

ParameterDialog::ParameterDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
    wxDialog(parent, id, title, pos, size, style)
{
    // begin wxGlade: ParameterDialog::ParameterDialog
    const wxString list_box_parameter_choices[] = {
        
    };
    list_box_parameter = new wxListBox(this, -1, wxDefaultPosition, wxDefaultSize, 0, list_box_parameter_choices, wxLB_MULTIPLE );
    button_add = new wxButton(this, ADD_STR, _("Add"));
    button_stream_add = new wxButton(this, ADD_CLIP, _("Add from\nClipBoard"));
    button_del = new wxButton(this, DEL_ONE, _("Delete"));
    button_ok = new wxButton(this, wxID_OK, _("OK"));
    button_cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));

    set_properties();
    do_layout();
    // end wxGlade
}


void ParameterDialog::set_properties()
{
    // begin wxGlade: ParameterDialog::set_properties
    list_box_parameter->SetMinSize(wxSize(150, 300));
    // end wxGlade
}


void ParameterDialog::do_layout()
{
    // begin wxGlade: ParameterDialog::do_layout
    wxBoxSizer* sizer_13 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* sizer_15 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_14 = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* sizer_16 = new wxBoxSizer(wxVERTICAL);
    sizer_14->Add(list_box_parameter, 0, wxALL, 5);
    sizer_16->Add(button_add, 0, wxALL, 3);
    sizer_16->Add(20, 20, 0, 0, 0);
    sizer_16->Add(button_stream_add, 0, wxALL, 3);
    sizer_16->Add(20, 20, 0, 0, 0);
    sizer_16->Add(button_del, 0, wxALL, 3);
    sizer_16->Add(20, 20, 1, 0, 0);
    sizer_14->Add(sizer_16, 1, wxEXPAND, 0);
    sizer_13->Add(sizer_14, 1, wxALL|wxEXPAND, 5);
    sizer_15->Add(button_ok, 1, wxALL, 10);
    sizer_15->Add(button_cancel, 1, wxALL, 10);
    sizer_13->Add(sizer_15, 0, wxALL|wxEXPAND, 5);
    SetAutoLayout(true);
    SetSizer(sizer_13);
    sizer_13->Fit(this);
    sizer_13->SetSizeHints(this);
    Layout();
    // end wxGlade
}

void ParameterDialog::Load(std::vector<double> list, bool editable, bool cancelable)
{
  if (!editable)
  {
    button_add->Enable(false);
    button_stream_add->Enable(false);
    button_del->Enable(false);
    button_ok->Enable(false);
  }

  if (!cancelable)
  {
    button_cancel->Enable(false);
  }

  list_box_parameter->Clear();
  for (int i=0; i<list.size(); ++i)
  {
    list_box_parameter->Append(wxString::Format("%g", list[i]));
  }
}

std::vector<double> ParameterDialog::Save()
{
  double tmp;
  std::vector<double> tmp_list;

  for (int i=0; i<list_box_parameter->GetCount(); ++i)
  {
    list_box_parameter->GetString(i).ToDouble(&tmp);
    tmp_list.push_back(tmp);
  }

  return tmp_list;
}

void ParameterDialog::OnAddStr(wxCommandEvent & event)
{
  wxString tmp = ::wxGetTextFromUser(_("Value ="), _("Input numbers"), wxEmptyString, this);

  std::vector<double> list =  readNumsfromString(tmp);
  for (int i=0; i<list.size(); ++i)
  {
    AddNumber(list[i]);
  }
}

void ParameterDialog::OnAddClip(wxCommandEvent & event)
{
  std::vector<double> list = readNumsfromClipboard();

  for (int i=0; i<list.size(); ++i)
  {
    AddNumber(list[i]);
  }
}

void ParameterDialog::OnDelOne(wxCommandEvent & event)
{
  int i;
  wxArrayInt slist;
  if ( (i = list_box_parameter->GetSelections(slist)) > 0 )
  {
    if (wxMessageBox(_("Do you really want to delete the item(s)?"), _("Confirm"), wxYES_NO|wxICON_INFORMATION, this) == wxYES)
    {
      for (int i = slist.Count() - 1; i >= 0; --i)
      {
        list_box_parameter->Delete(slist[i]);
      }
    }
  }
}

void ParameterDialog::AddNumber(double value)
{
  double tmp;

  for (int i=0; i<list_box_parameter->GetCount(); ++i)
  {
    list_box_parameter->GetString(i).ToDouble(&tmp);
    if (value < tmp)
    {
      list_box_parameter->Insert(wxString::Format("%g", value), i);
      return;
    }
    else if (value == tmp)
    {
      return;
    }
  }
  list_box_parameter->Append(wxString::Format("%g", value));  
}
